/*************************************************
* MD4 Header File                                *
* (C) 1999-2002 The Botan Project                *
* Modifications (C) 2003 Llew goodstadt          *
*************************************************/

#ifndef MINI_BOTAN_MD4_H__
#define MINI_BOTAN_MD4_H__

#include <string>
#include "digest.h"

namespace mini_Botan {
/*************************************************
* MD4                                            *
*************************************************/
class MD4
	{

    public:
		MD4();
		void process(const std::string& in, unsigned digest[]);
		void process(const unsigned char* input, unsigned length, unsigned result[]);

	private:
		typedef unsigned long long u64bit;
		typedef unsigned char byte;
		enum {HASH_BLOCK_SIZE = 64, OUTPUT_LENGTH = 16};
		unsigned					position;
		byte 						buffer[64];
		unsigned					M[16];
		unsigned					digest[4];
		// remember to keep count a 64 bit value for digest extraction
		u64bit						count;
		void hash(const byte[]);
		void clear();
		static void FF(unsigned&, unsigned, unsigned, unsigned, unsigned, byte);
		static void GG(unsigned&, unsigned, unsigned, unsigned, unsigned, byte);
		static void HH(unsigned&, unsigned, unsigned, unsigned, unsigned, byte);
		//utility functions
		void copy(byte buf[], unsigned off, const byte in[], unsigned n);
		template<typename T> byte get_byte(unsigned byte_num, T input);
		unsigned make_unsigned(byte input0, byte input1, byte input2, byte input3);
	};

}

inline t_digest& md4_hash(const unsigned char* s, unsigned length, t_digest& hv)
{
	mini_Botan::MD4	md4;
	md4.process(s, length, hv.digest);
	return hv;
}

inline t_digest& md4_hash(const std::string& s, t_digest& hv)
{
	mini_Botan::MD4	md4;
	md4.process(s, hv.digest);
	return hv;
}

inline t_digest& md4_hash(	const std::string::const_iterator& beg,
							const std::string::const_iterator& end, t_digest& hv)
{
	const std::string tobe_hashed(beg, end);
	return md4_hash(tobe_hashed, hv);
}


#endif


